package co.yixiang.yshop.module.pay.processor;

import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.util.servlet.ServletUtils;
import co.yixiang.yshop.module.member.api.user.MemberUserApi;
import co.yixiang.yshop.module.member.api.user.dto.MemberUserRespDTO;
import co.yixiang.yshop.module.order.api.productorder.ProductOrderApi;
import co.yixiang.yshop.module.order.api.productorder.dto.ProductOrderDTO;
import co.yixiang.yshop.module.order.api.rechargeorder.RechargeOrderApi;
import co.yixiang.yshop.module.order.api.rechargeorder.dto.RechargeOrderDTO;
import co.yixiang.yshop.module.pay.controller.admin.merchantdetails.vo.PayParam;
import co.yixiang.yshop.module.pay.dal.dataobject.merchantdetails.MerchantDetailsDO;
import co.yixiang.yshop.module.pay.enums.PayOrderConstants;
import co.yixiang.yshop.module.pay.enums.PayTypeEnum;
import co.yixiang.yshop.module.pay.service.merchantdetails.MerchantDetailsService;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.HttpKit;
import co.yixiang.yshop.module.pay.strategy.weixin.skd.PaymentKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import java.math.BigDecimal;
import java.util.Map;
import java.util.Objects;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.USER_NOT_BINDING_WX_APPLET;

/**
 * 支付订单处理器实现
 */
@Slf4j
@Service
public class PayOrderProcessorImpl implements PayOrderProcessor {

    @Resource
    private MemberUserApi memberUserApi;

    @Resource
    private RechargeOrderApi rechargeOrderApi;

    @Resource
    private ProductOrderApi productOrderApi;

    @Resource
    private MerchantDetailsService merchantDetailsService;


    @Override
    public PayParam getPayParam(String orderId, String payType) {
        Long userId = getLoginUserId();
        MemberUserRespDTO user = memberUserApi.getUser(userId);
        if (PayTypeEnum.WEIXIN_APPLET.getType().equals(payType)) {
            //小程序支付需要openid
            if (Objects.isNull(user.getRoutineOpenId())) throw exception(USER_NOT_BINDING_WX_APPLET);
        }
        // 充值参数
        PayParam payParam = new PayParam();
        payParam.setOrderId(orderId);
        payParam.setOpenId(user.getRoutineOpenId());
        payParam.setIp(ServletUtils.getClientIP());
        payParam.setPayDesc(PayOrderConstants.PAY_DESC);

        // 判断是否为充值
        if (StrUtil.startWith(orderId, PayOrderConstants.RECHARGE_ORDER_PREFIX)) {
            RechargeOrderDTO rechargeOrderDTO = rechargeOrderApi.getPayParam(orderId);
            payParam.setMoney(new BigDecimal(rechargeOrderDTO.getRechargeAmount()));
            payParam.setRedirectType(PayOrderConstants.RECHARGE_REDIRECT_URL);
        } else {
            // 不是充值就是购买
            ProductOrderDTO productOrderDTO = productOrderApi.getPayParam(orderId);
            payParam.setMoney(productOrderDTO.getAmount());
            payParam.setRedirectType(PayOrderConstants.PAY_REDIRECT_URL);
        }

        return payParam;
    }

    @Override
    public void handelWait(String orderId, Map<String, String> packageParams) {
        // 判断是否为充值
        if (StrUtil.startWith(orderId, PayOrderConstants.RECHARGE_ORDER_PREFIX)) {
            // 充值
        } else {
            // 不是充值就是购买
            productOrderApi.handleOrder(orderId, packageParams);
        }
    }

    @Override
    public void handleWeChatPayNotify(HttpServletRequest request) throws Exception {
        log.info("进入微信支付回调");
        String xmlMsg = HttpKit.readData(request);
        log.info("微信回调通知信息" + xmlMsg);
        if (StringUtils.isEmpty(xmlMsg)) {
            log.info("回调接口内容为空！");
            return;
        }
        Map<String, String> resultMap = PaymentKit.xmlToMap(xmlMsg);
        //验签
        MerchantDetailsDO merchantDetailsDO = merchantDetailsService.getMerchantDetails();
        boolean validSignResult = PaymentKit.verifyNotify(resultMap, merchantDetailsDO.getKeyPrivate());
        log.info("验签结果{}", validSignResult);
        if (MapUtils.isEmpty(resultMap)) {
            log.info("map为null");
            return;
        }
        log.info("=====> 回调结果映射 resultMap :{}",resultMap);

        if (!resultMap.get("return_code").equals("SUCCESS")) {
            log.info("return_code不是SUCCESS");
            return;
        }
        String orderNo = resultMap.get("out_trade_no");
        log.info("回调out_trade_no=" + orderNo);
        log.info("回调transaction_id=" + resultMap.get("transaction_id"));
        //截取订单编号
        String[] split = orderNo.split("-");
        if (split.length == 0) {
            log.info("截取id为null");
        }
        String orderId = split[0];
        if (StringUtils.isEmpty(orderId)) {
            log.info("orderId为null");
        }
        // 判断是否为充值
        if (StrUtil.startWith(orderId, PayOrderConstants.RECHARGE_ORDER_PREFIX)) {
            // 充值
            rechargeOrderApi.handleWeChatPayNotify(orderId);
        } else {
            // 不是充值就是购买
            productOrderApi.handleWeChatPayNotify(orderId, resultMap);
        }


    }
}
